package com.ala4.oxcafe.async;

import com.ala4.oxcafe.boot.manager.CustomUserDetails;
import com.ala4.oxcafe.boot.utils.DetailsHelper;
import org.slf4j.MDC;
import org.springframework.boot.task.ThreadPoolTaskExecutorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskDecorator;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.util.Map;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 异步线程配置
 *
 * @author PING
 * @date 2025/8/17 14:43
 */
@Configuration
public class AsyncConfig {

    @Bean
    public TaskExecutor taskExecutor(ThreadPoolTaskExecutorBuilder builder) {

        OperatingSystemMXBean osBean = ManagementFactory.getOperatingSystemMXBean();
        int cores = osBean.getAvailableProcessors();
        ThreadPoolTaskExecutor threadPoolTaskExecutor = builder.corePoolSize(cores)
                .maxPoolSize(cores * 2)
                .queueCapacity(cores * 2 * 3)
                .allowCoreThreadTimeOut(true)
                .acceptTasksAfterContextClose(false)
                .threadNamePrefix("auto-async-")
                .build();

        // 拒绝策略-调用者执行
        threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 设置装饰器
        threadPoolTaskExecutor.setTaskDecorator(compositeDecorator());

        threadPoolTaskExecutor.initialize();

        return threadPoolTaskExecutor;
    }

    /**
     * 线程装饰器 用来设置上下文和日志ID
     *
     * @return
     */
    @Bean
    public TaskDecorator compositeDecorator() {
        TaskDecorator securityDecorator = securityContextTaskDecorator();
        TaskDecorator mdcDecorator = mdcTaskDecorator();

        return runnable -> {
            Runnable wrapped = securityDecorator.decorate(runnable);
            wrapped = mdcDecorator.decorate(wrapped);
            return wrapped;
        };
    }

    /**
     * 设置用户信息上下文
     *
     * @return
     */
    public TaskDecorator securityContextTaskDecorator() {
        return runnable -> {
            CustomUserDetails userDetails = DetailsHelper.getUserDetails();
            return () -> {
                try {
                    DetailsHelper.setCustomUserDetails(userDetails);
                    runnable.run();
                } finally {
                    DetailsHelper.clearContext();
                }
            };
        };
    }

    public TaskDecorator mdcTaskDecorator() {
        return runnable -> {
            Map<String, String> mdcContext = MDC.getCopyOfContextMap();
            return () -> {
                try {
                    if (mdcContext != null) {
                        MDC.setContextMap(mdcContext);
                    }
                    runnable.run();
                } finally {
                    MDC.clear();
                }
            };
        };
    }


//    @Bean
//    public Executor asyncExecutor(MeterRegistry registry) {
//        ThreadPoolTaskExecutor executor = ...;
//        // 绑定监控指标
//        new ThreadPoolTaskExecutorMetrics(executor, "app.async", Collections.emptyList())
//                .bindTo(registry);
//        return executor;
//    }

}
